#include "read_boy_confg.h"
#include "readboy_epd_4_2B.h"
#include "read_boy.h"

#if defined(READ_BOY_DEV_4_2B) 


drv_Base_t my_drv_base;
void read_boy_4_2b_drv_Init(uint8_t pt);
void read_boy_4_2b_drv_init(){//=========================================
  my_drv_base.part_mode=0;
  my_drv_base.Power_is_on=0;
  readboyEpdBase_BeginTransfer();
  read_boy_4_2b_drv_Init(0);
  readboyEpdBase_EndTransfer();
  //drv_color(0xffu);
}


void read_boy_4_2b_drv();
void my_drv_base_init(){
    my_drv_base.iLut = 15;
    my_drv_base.sleeping = 1;
    my_drv_base.epdWidth = 400;
    my_drv_base.epdHeight = 300;
    //my_drv_base.idleFastRf = 350;
    //my_drv_base.idleSlowRf = 1300;
    
    my_drv_base.epdFull = 2;// //是partical模式/快速刷新模式 0快刷, 1慢刷
    my_drv_base.GreyScalingHighQuality = 0;
    my_drv_base.Power_is_on = 0  ; //初始为未上电
    my_drv_base.GreyScaling = 0; //是否正在灰度显示
    my_drv_base.part_mode = 1;
    
    my_drv_base.in_trans = 0;
    my_drv_base._quality = 3; //灰度显示品质 默认2 0,2-高品质 1,3-低品质高兼容性. 0,1使用bayer灰度二值表 2,3使用floyd算法   
    my_drv_base.lastRefresh = 0;
    
    my_drv_base.drv_fullpart = &read_boy_4_2b_drv_fullpart;
    my_drv_base.drv_setDepth = &drv_setDepth;
    my_drv_base.drv_sleep = &read_boy_4_2b_drv_sleep;
//    my_drv_base.lut_Init = &read_boy_4_2a_drv_SetLut;//===============================================================
    my_drv_base.drv_dispWriter = &read_boy_4_2b_drv_dispWriter;
    
    read_boy_4_2b_drv();

    read_boy_4_2b_drv_init();
}

const   unsigned char drv_lut_vcom0[] ={
  0x00, 0x08, 0x08, 0x00, 0x00, 0x02,  
  0x00, 0x0F, 0x0F, 0x00, 0x00, 0x01, 
  0x00, 0x08, 0x08, 0x00, 0x00, 0x02
};
const   unsigned char drv_lut_ww[] ={
  0x50, 0x08, 0x08, 0x00, 0x00, 0x02, 
  0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01, 
  0xA0, 0x08, 0x08, 0x00, 0x00, 0x02
};
const   unsigned char drv_lut_bw[] ={
  0x50, 0x08, 0x08, 0x00, 0x00, 0x02, 
  0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01, 
  0xA0, 0x08, 0x08, 0x00, 0x00, 0x02
};
const   unsigned char drv_lut_bb[] ={
  0x20, 0x08, 0x08, 0x00, 0x00, 0x02, 
  0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01, 
  0x10, 0x08, 0x08, 0x00, 0x00, 0x02
};
const   unsigned char drv_lut_wb[] ={
  0xA0, 0x08, 0x08, 0x00, 0x00, 0x02, 
  0x90, 0x0F, 0x0F, 0x00, 0x00, 0x01, 
  0x50, 0x08, 0x08, 0x00, 0x00, 0x02
};
const   unsigned char drv_lutFast_vc0[] ={ 0x00,2,0,48,0,1 };
const   unsigned char drv_lutFast_w_w[] ={ 0x02,2,0,48,0,1 };
const   unsigned char drv_lutFast_b_w[] ={ 0x5a,2,0,63,0,1 };
const   unsigned char drv_lutFast_w_b[] ={ 0x84,2,0,48,0,1 };
const   unsigned char drv_lutFast_b_b[] ={ 0x01,2,0,48,0,1 };

const   uint8_t drv_greyTable[16]={
  32,23,18,15,12,10,9,8,
  7,6,5,5,5,5,5,0
};


const unsigned char *guy_lutArray[16];
const int CUSTOM_LUT_DISABLE =48;

void read_boy_4_2b_drv(){
  guy_lutArray[0] = drv_lut_vcom0;
  guy_lutArray[1] = drv_lut_ww;
  guy_lutArray[2] = drv_lut_bw;
  guy_lutArray[3] = drv_lut_wb;
  guy_lutArray[4] = drv_lut_bb;
  guy_lutArray[5] = drv_lutFast_vc0;
  guy_lutArray[6] = drv_lutFast_w_w;
  guy_lutArray[7] = drv_lutFast_b_w;
  guy_lutArray[8] = drv_lutFast_w_b;
  guy_lutArray[9] = drv_lutFast_b_b;
  my_drv_base.customLut=CUSTOM_LUT_DISABLE;
  my_drv_base.customGreyscale=0;
}




void read_boy_4_2b_drv_Init(uint8_t pt) {
  readboyEpdBase_Reset(20);  //Reset();
  readboyEpdBase_boy_epdCmd(0x00); //Software reset
  readboyEpdBase_boy_epdParam(0x00);
  Delayus(40);
  readboyEpdBase_boy_epdCmd(0x00);
  readboyEpdBase_boy_epdParam(0x1f);
  readboyEpdBase_boy_epdParam(0x0d);
  Delayus(40);
  readboyEpdBase_boy_epdCmd(0x50);
  readboyEpdBase_boy_epdParam(0x97);
  Delayus(40);
  readboyEpdBase_boy_epdCmd(0x01);
  readboyEpdBase_boy_epdParam(0x03);
  readboyEpdBase_boy_epdParam(0x00);
  readboyEpdBase_boy_epdParam(0x2b);
  readboyEpdBase_boy_epdParam(0x2b);
  Delayus(40);
  readboyEpdBase_boy_epdCmd(0x06);
  readboyEpdBase_boy_epdParam(0x17);
  readboyEpdBase_boy_epdParam(0x17);
  readboyEpdBase_boy_epdParam(0x17);
  Delayus(40);
  readboyEpdBase_boy_epdCmd(0x00);
  readboyEpdBase_boy_epdParam(0x3f);
  Delayus(40);
  readboyEpdBase_boy_epdCmd(0x30);
  readboyEpdBase_boy_epdParam(0x3a);
  Delayus(40);
  readboyEpdBase_boy_epdCmd(0x61);
  readboyEpdBase_boy_epdParam(0x01);
  readboyEpdBase_boy_epdParam(0x90);
  readboyEpdBase_boy_epdParam(0x01);
  readboyEpdBase_boy_epdParam(0x2c);
  Delayus(40);
  readboyEpdBase_boy_epdCmd(0x82); //vcom setting: 0x00:-0.1V, 0x3a: -3.0V
  readboyEpdBase_boy_epdParam(0x1a);
  Delayus(40);
  readboyEpdBase_boy_epdCmd(0x50);
  readboyEpdBase_boy_epdParam(0xd7);
  Delayus(40);
  //不知为何, 此处需要快刷lut
  for(uint8_t i=0;i<=4;i++){ //for(uint8_t i=0;i<=(lutOption==2?5:4);i++){
    readboyEpdBase_boy_epdCmd(i+0x20);
    for(int j=0;j<(pt?6:(i+pt==0?44:42));j++){
      if(j==2 && my_drv_base.customGreyscale) readboyEpdBase_boy_epdParam(63);
      else if(j==3 && i!=2) readboyEpdBase_boy_epdParam(my_drv_base.customLut);
      else {
          //guy_epdParam(j<18?pgm_read_byte(guy_lutArray[i+(pt?1:0)*5]+j):0x00);
          readboyEpdBase_boy_epdParam(j<18?guy_lutArray[i+(pt?1:0)*5][j]:0x00);//(guy_lutArray[i+(pt?1:0)*5]+j):0x00);
      }
      Delayus(40);
    }
  }
  if(pt!=2) readboyEpdBase_boy_epdCmd(0x04);
  Delayus(40);
}

void read_boy_4_2b_drv_sendAreaRaw(){
  readboyEpdBase_boy_epdCmd(0x90);
  readboyEpdBase_boy_epdParam(0x00);
  readboyEpdBase_boy_epdParam(0x00);
  readboyEpdBase_boy_epdParam(0x01);
  readboyEpdBase_boy_epdParam(0x8f);
  readboyEpdBase_boy_epdParam(0x00);
  readboyEpdBase_boy_epdParam(0x00);
  readboyEpdBase_boy_epdParam(0x01);
  readboyEpdBase_boy_epdParam(0x2b);
  readboyEpdBase_boy_epdParam(0x01);
}
void read_boy_4_2b_drv_sendArea(){
  readboyEpdBase_boy_epdCmd(0x91);
  read_boy_4_2b_drv_sendAreaRaw();
}

void read_boy_4_2b_drv_dispWriter(read_boy_drv_dispWriter_t* f,uint8_t m){ //单色刷新

  if(m&1){//stage 1
  if(my_drv_base.lastRefresh) read_boy_4_2b_drv_dispWriter(f,2);
  readboyEpdBase_BeginTransfer();
  read_boy_4_2b_drv_Init(my_drv_base.part_mode);
  if(my_drv_base.part_mode){
    read_boy_4_2b_drv_sendArea();
    readboyEpdBase_boy_epdCmd(0x13);
    for(int i=0;i<my_drv_base.epdWidth*my_drv_base.epdHeight/8;i++)
      SpiTransfer(f(i));
    //data
    readboyEpdBase_boy_epdCmd(0x92);
    read_boy_4_2b_drv_sendAreaRaw();//sendAreaRaw();
    //[EPDrg_BW<>] refresh fx
  }
  else{
    my_drv_base.Power_is_on=1;
    readboyEpdBase_boy_epdCmd(0x10);
    //刷新数据
    for(int i=0;i<my_drv_base.epdWidth*my_drv_base.epdHeight/8;i++)
      SpiTransfer(f(i));
    readboyEpdBase_boy_epdCmd(0x13);
    //刷新数据
    for(int i=0;i<my_drv_base.epdWidth*my_drv_base.epdHeight/8;i++)
      SpiTransfer(f(i));
    readboyEpdBase_boy_epdCmd(0x92);
    //[EPDrg_BW<>] refresh fx
    readboyEpdBase_boy_epdCmd(0x00);
    readboyEpdBase_boy_epdParam(0x1f);
    readboyEpdBase_boy_epdParam(0x0d);
    readboyEpdBase_boy_epdCmd(0x50);
    readboyEpdBase_boy_epdParam(0x97);
    //[EPDrg_EPD] wait_until_idle fx: 5000
  }
  readboyEpdBase_boy_epdCmd(0x12);
  readboyEpdBase_EndTransfer();
  my_drv_base.lastRefresh=0;//millis();
  }
  if(m&2){//stage 2
    uint32_t ms=0-my_drv_base.lastRefresh;
    int32_t u=my_drv_base.part_mode?800:3600;
    if((int32_t)ms<u) readboyEpdBase_boy_epdBusy((int32_t)ms-u);
    my_drv_base.lastRefresh=0;
  readboyEpdBase_BeginTransfer();
  if(my_drv_base.part_mode){
    read_boy_4_2b_drv_sendArea();
    readboyEpdBase_boy_epdCmd(0x13);
    for(int i=0;i<my_drv_base.epdWidth*my_drv_base.epdHeight/8;i++)
      SpiTransfer(f(i));
    readboyEpdBase_boy_epdCmd(0x92);
  }
  else{
    read_boy_4_2b_drv_Init(2);
    read_boy_4_2b_drv_sendArea();
    readboyEpdBase_boy_epdCmd(0x13);
    for(int i=0;i<my_drv_base.epdWidth*my_drv_base.epdHeight/8;i++)
      SpiTransfer(f(i));
    readboyEpdBase_boy_epdCmd(0x92);
    readboyEpdBase_boy_epdCmd(0x02);
  }
    readboyEpdBase_EndTransfer();
    readboyEpdBase_boy_epdBusy(-20);
  }
}



void read_boy_4_2b_drv_fullpart(bool part){ //切换慢刷/快刷功能
  if(my_drv_base.lastRefresh) return;
  if(my_drv_base.Power_is_on) {
    if(!part) my_drv_base.customLut = CUSTOM_LUT_DISABLE;
    my_drv_base.part_mode = part;
    //Init(part);
  }
}

void drv_setDepth(uint8_t i) {
      my_drv_base.part_mode=1;
      if(i) my_drv_base.customLut = i>15?45:i*3;
      else my_drv_base.customLut = CUSTOM_LUT_DISABLE;
    } //设置显示颜色深度

void read_boy_4_2b_drv_sleep() { //开始屏幕睡眠
  //if(RST_PIN>=0){ //未定义RST_PIN时无法唤醒
    readboyEpdBase_BeginTransfer();
    readboyEpdBase_boy_epdCmd(0x02);          //power off
    readboyEpdBase_EndTransfer();
    readboyEpdBase_boy_epdBusy(-30);
    readboyEpdBase_BeginTransfer();
    readboyEpdBase_boy_epdCmd(0x07);         //deep sleep
    readboyEpdBase_boy_epdParam(0xA5);
    readboyEpdBase_EndTransfer();
  //}
  my_drv_base.Power_is_on=0;
  my_drv_base.part_mode=0;
}

#endif









































